package study.http.client;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Collections;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Node;
import org.dom4j.xpath.DefaultXPath;

/**  
* @Name: HttpClientSoap11
* @Description: 模拟浏览器向webservice发送post请求，数据的内容是soap1.2协议体。
* @Author: 李超
* @version 1.0
* @Create Date: 2017-01-07
*/
public class HttpClientSoap12 {
	public static void main(String[] args) throws IOException, DocumentException {
		//请求的webservice服务的url
		URL url = new URL("http://127.0.0.1:12345/weather") ;
		//创建http连接
		HttpURLConnection connection = (HttpURLConnection) url.openConnection() ;
		//设置请求的方法类型
		connection.setRequestMethod("POST") ;
		//设置请求的内容类型：Content-type
		connection.setRequestProperty("Content-type", "application/soap+xml;charset=\"utf-8\"") ;
		//设置发送数据状态
		connection.setDoOutput(true) ;
		//设置接收数据状态
		connection.setDoInput(true) ;
		//发送数据，使用输出流
		OutputStream outputStream = connection.getOutputStream() ;
		//获取发送soap协议的字符串数据
		String requestXmlString = requestXml("北京") ;
		//发送数据
		outputStream.write(requestXmlString.getBytes()) ;
		//接收数据，使用输入流
		InputStream inputStream = connection.getInputStream() ;
		//定义字节数据，作为buffer
		//定义字节数组作为buffer
		byte[] b = new byte[1024] ;
		//定义字节输出流存储接收到的数据
		ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream() ;
		//开始接收数据
		int len = 0 ;
		while(true) {
			len = inputStream.read(b) ;
			if(len == -1) {
				//数据读完
				break ;
			}
			byteArrayOutputStream.write(b, 0, len) ;
		}
		//从字节输出流中获取接收到的数据（服务端返回的数据）
		String responseData = byteArrayOutputStream.toString() ;
		System.out.println("soap响应的xml内容：" + responseData);
		//解析接收到的xml数据，得到结果数据
		String result = parseXml(responseData) ;
		System.out.println("解析后的结果：" + result);
	}
	
	/**  
	* @Name: requestXml（方法的名称）
	* @Description: 生成请求的soap协议体数据（方法的描述）
	* 	<?xml version="1.0" ?>
		<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope">
			<S:Body>
				<ns2:queryWeather xmlns:ns2="http://impl.jaxws.service.web.study/">
					<arg0>北京</arg0>
				</ns2:queryWeather>
			</S:Body><
		/S:Envelope>
	* @Author: 李超（作者）
	* @Version: V1.00 （版本号）
	* @Create Date: 2017-01-06 （创建日期）
	* @Parameters: String cityName 请求参数（方法的入参，如果没有，填写为“无”）
	* @Return: String 返回请求的soap协议体数据（返回值，如果没有，填写为“无”）
	*/
	private static String requestXml(String cityName) {
		String xmlString = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
				+ "<S:Envelope xmlns:S=\"http://www.w3.org/2003/05/soap-envelope\">"
				+ "<S:Body>"
				+ "<ns2:queryWeather xmlns:ns2=\"http://impl.jaxws.service.web.study/\">"
				+ "<arg0>" + cityName + "</arg0>"
				+ "</ns2:queryWeather>"
				+ "</S:Body>"
				+ "</S:Envelope>" ;
		return xmlString ;
	}
	
	/**  
	* @Name: parseXml（方法的名称）
	* @Description: 解析soap响应的xml数据（方法的描述）
	* 	<?xml version='1.0' encoding='UTF-8'?>
		<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope">
			<S:Body>
				<ns2:queryWeatherResponse xmlns:ns2="http://impl.jaxws.service.web.study/">
					<return>多云</return>
				</ns2:queryWeatherResponse>
			</S:Body>
		</S:Envelope>
	* @Author: 李超（作者）
	* @Version: V1.00 （版本号）
	* @Create Date: 2017-01-07 （创建日期）
	* @Parameters: String responseString soap响应的xml数据字符串（方法的入参，如果没有，填写为“无”）
	* @Return: String 返回解析结果（返回值，如果没有，填写为“无”）
	*/
	private static String parseXml(String responseString) throws DocumentException {
		String result = null ;
		//创建dom4j文档对象
		Document document = DocumentHelper.parseText(responseString) ;
		//创建xpath对象
		DefaultXPath defaultXPath = new DefaultXPath("//ns2:queryWeatherResponse") ;
		defaultXPath.setNamespaceURIs(Collections.singletonMap("ns2", "http://impl.jaxws.service.web.study/")) ;
		Node node_queryWeatherResponse = defaultXPath.selectSingleNode(document) ;
		Node node_return = node_queryWeatherResponse.selectSingleNode("return") ;
		//使用xpath方式获取soap响应的结果数据
		//Node node = document.selectSingleNode("//queryWeatherResponse/return") ;
		//result = node.getText() ;
		result = node_return.getText() ;
		return result ;
	}
	
}











